﻿using FlyingHat.Common.Helper;
using FlyingHat.Core.Core.CurrentUser;
using FlyingHat.Model.Enums;
using Microsoft.EntityFrameworkCore;

namespace FlyingHat.Core.Entities
{
    public class BaseContext : DbContext
    {
        private readonly ICurrentUser? currentUser = ServicesHelper.GetScopeService<ICurrentUser>();
        public BaseContext(DbContextOptions<BaseContext> options) : base(options)
        {
        }

        public virtual DbSet<User> User => Set<User>();
        public virtual DbSet<Book> Book => Set<Book>();
        public virtual DbSet<BookClassification> BookClassification => Set<BookClassification>();
        public virtual DbSet<Bookshelf> Bookshelf => Set<Bookshelf>();
        public virtual DbSet<BookshelfClassification> BookshelfClassification => Set<BookshelfClassification>();
        public virtual DbSet<BorrowReturnBook> BorrowReturnBook => Set<BorrowReturnBook>();
        public virtual DbSet<Classification> Classification => Set<Classification>();
        public virtual DbSet<Library> Library => Set<Library>();
        public virtual DbSet<Log> Log => Set<Log>();
        public virtual DbSet<UserLog> UserLog => Set<UserLog>();


        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            var salt = EncryptHelper.GetSalt();
            var pwd = EncryptHelper.GetPassword($"123456", salt);
            var u = new User()
            {
                Id = 1,
                UserName = "flyinghat",
                RealName = "超级管理员",
                Password = pwd,
                Salt = salt,
                UserStatus = UserStatus.Enable,
                Gender = Gender.Male,
                Identity = Identity.SuperAdmin,
                LastLoginTime = DateTime.Now,
            };
            modelBuilder.Entity<User>().HasData(u);
            base.OnModelCreating(modelBuilder);
        }

        public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
        {
            // 扫描跟踪的实体实例以检测对实例数据所做的任何更改
            ChangeTracker.DetectChanges();
            ChangeTracker.AutoDetectChangesEnabled = false;

            var add = ChangeTracker.Entries().Where(i => i.State == EntityState.Added && i.Entity is CreateEntity);
            foreach (var item in add)
            {
                var entity = item.Entity as CreateEntity;
                if (entity != null)
                {
                    entity.CreatedTime = DateTime.Now;
                    entity.CreatedUserId = currentUser?.Id ?? 0;
                }
            }
            var edit = ChangeTracker.Entries().Where(i => i.State == EntityState.Modified && i.Entity is ModifyEntity);
            foreach (var item in edit)
            {
                var entity = item.Entity as ModifyEntity;
                if (entity != null)
                {
                    item.Property(nameof(entity.ModifyTime)).IsModified = true;
                    item.Property(nameof(entity.ModifyUserId)).IsModified = true;
                    entity.ModifyTime = DateTime.Now;
                    entity.ModifyUserId = currentUser?.Id ?? 0;
                }
            }
            var row = await base.SaveChangesAsync(cancellationToken);
            ChangeTracker.AutoDetectChangesEnabled = true;
            return row;
        }

    }
}
